package com.qf.shop.goods.controller;

import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.qf.shop.common.exception.BusinessException;
import com.qf.shop.common.vo.GoodsPngVO;
import com.qf.shop.goods.entity.GoodsPngEntity;
import com.qf.shop.goods.entity.StockEntity;
import com.qf.shop.goods.service.GoodsPngService;
import com.qf.shop.goods.service.StockService;
import com.qf.shop.common.vo.GoodsVo;
import com.qf.shop.goods.utils.VoUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import com.qf.shop.goods.entity.GoodsEntity;
import com.qf.shop.goods.service.GoodsService;
import com.qf.shop.common.utils.PageUtils;
import com.qf.shop.common.utils.R;
import org.springframework.web.multipart.MultipartFile;


/**
 * 商品管理
 *
 * @author Java2103
 * @email Java2103@qq.com
 * @date 2021-08-03 09:14:52
 */
@RestController
@RequestMapping("/goods")
@Slf4j
public class GoodsController {
    @Autowired
    private GoodsService goodsService;

    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    @Autowired
    private GoodsPngService goodsPngService;

    @Value("${fdfs.fastPath}")
    private String fastPath;

    @Autowired
    private StockService stockService;

    @Autowired
    private RedissonClient client;

    private static final String SHOP_GOODS_VO_LOCK_PRE = "shop:goods:lock:";

    private static final String SHOP_GOODS_VO_PRE = "shop:goods:vo:";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    // file
    @RequestMapping("/fileUpload")
    public R fileUpload(MultipartFile file) throws Exception {

        // 3.获取文件的后缀
        String fileExtension = FilenameUtils.getExtension(file.getOriginalFilename());

        // 3.上传
        InputStream ips = file.getInputStream();
        long size = file.getSize();
        StorePath storePath = fastFileStorageClient.uploadImageAndCrtThumbImage(ips, size, fileExtension, null);

        // 4.获取文件地址
        String url = storePath.getFullPath();

        return R.ok().put("url", fastPath + url);
    }

    @GetMapping("/test")
    public String test(Integer id) {
        System.out.println("id = " + id);
        if (id == 0) {
            throw new BusinessException("id不能为空", 555); // 业务异常
        }
        int x = 10 / id;
        return "test:" + id;
    }

    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params) {

        // 1.只能查询出商品信息出来
        PageUtils page = goodsService.queryPage(params);

        // 2.获取当前页显示的数据(商品信息)
        List<GoodsEntity> goodsEntityList = (List<GoodsEntity>) page.getList();

        // 3、创建一个GoodsVOList
        List<GoodsVo> goodsVoList = new ArrayList<GoodsVo>();

        // 4.拷贝
        for (GoodsEntity goodsEntity : goodsEntityList) {
            GoodsVo goodsVo = new GoodsVo();

            // 拷贝商品的信息
            BeanUtils.copyProperties(goodsEntity, goodsVo);

            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("gid", goodsEntity.getId());
            List<GoodsPngEntity> list = goodsPngService.list(queryWrapper);
            // 查询商品的图片
            goodsVo.setGoodsPngList(VoUtils.goodsPngEntityToGoodsPngVO(list)); // 根据商品的id查询商品的图片

            // 添加到VO的集合中
            goodsVoList.add(goodsVo);
        }

        log.debug("goodsEntityList:{}", goodsEntityList);
        log.debug("goodsVoList:{}", goodsVoList);
        page.setList(goodsVoList);
        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Integer id) {
        GoodsEntity goods = goodsService.getById(id);

        return R.ok().put("goods", goods);
    }

    @GetMapping("/getGoodsVoById/{id}")
    public GoodsVo getGoodsVoById(@PathVariable("id") Integer id) {
        return JSON.parseObject(getDbGoodsVo(id), GoodsVo.class);
    }

    private String getDbGoodsVo(Integer id) {
        // 1.先查询缓存
        String goodsVoJSON = stringRedisTemplate.opsForValue().get(SHOP_GOODS_VO_PRE+id);
        if (!StringUtils.isEmpty(goodsVoJSON)) {
            return goodsVoJSON;
        }

        // 1.获取锁
        RLock goodsVoLock = client.getLock(SHOP_GOODS_VO_LOCK_PRE + id);

        // 2.加锁
        boolean b = goodsVoLock.tryLock();
        if (b) {
            try {
                GoodsVo goodsVo = goodsService.getGoodsVoById(id);
                String v = JSON.toJSONString(goodsVo);
                stringRedisTemplate.opsForValue().set(SHOP_GOODS_VO_PRE+id, v, 7, TimeUnit.DAYS);
                return v;
            } finally {
                // 3.释放锁
                goodsVoLock.unlock();
            }
        } else {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return getDbGoodsVo(id);
        }
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody GoodsVo goods) {
        log.debug("GoodsVO:{}", goods);

        goodsService.addGoods(goods);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody GoodsEntity goods) {
        goodsService.updateById(goods);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Integer[] ids) {
        goodsService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

    @GetMapping("/getAll")
    public List<GoodsVo> getAll() {
//        List<GoodsVo> goodsVoList = new ArrayList<>();
//
//        // 1.查询所有的商品信息
//        List<GoodsEntity> goodsEntityList = goodsService.list();
//
//        for (GoodsEntity goodsEntity : goodsEntityList) {
//            GoodsVo goodsVo = new GoodsVo();
//
//            // 拷贝商品的信息到GoodsVO
//            BeanUtils.copyProperties(goodsEntity, goodsVo);
//
//            // 查询商品的图片
//            QueryWrapper queryWrapper = new QueryWrapper();
//            queryWrapper.eq("gid", goodsEntity.getId());
//            List<GoodsPngEntity> list = goodsPngService.list(queryWrapper);
//            goodsVo.setGoodsPngList(VoUtils.goodsPngEntityToGoodsPngVO(list)); // 根据商品的id查询商品的图片
//
//            // 库存
//            QueryWrapper queryWrapperStock = new QueryWrapper();
//            queryWrapperStock.eq("gid", goodsEntity.getId());
//            StockEntity stockEntity = stockService.getOne(queryWrapperStock);
//            goodsVo.setStock(stockEntity.getStock());
//
//
//            // 查询商铺信息
//
//            // 添加到VO的集合中
//            goodsVoList.add(goodsVo);
//        }
        return goodsService.getGoodsVoList();
    }

}
